package com.example.pathofexilequalitysolver;

import java.util.Arrays;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
    public void reset(View view) {
    	EditText editText = (EditText) findViewById(R.id.editText1);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText2);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText3);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText4);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText5);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText6);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText7);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText8);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText9);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText10);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText11);
        editText.setText("0");
    	editText = (EditText) findViewById(R.id.editText12);
        editText.setText("0");
        editText = (EditText) findViewById(R.id.resultbox);
        editText.setText("Enter up to 12 qualities and click Solve. (Leave unused boxes as 0.)");
    }
    
    public int sanitize(String number) {
    	int x = Integer.parseInt(number);
    	if (x < 0) {
    		x=0;
    	}
    	if (x > 20) {
    		x=0;
    	}
    	return(x);
    }
    
    //Array reversing function copyleft Fred Swartz.
    //Thanks, guy with handy knowledge of array manipulation! You rock! :)
    //Taken from: http://leepoint.net/notes-java/data/arrays/arrays-ex-reverse.html
    //MIT License: http://opensource.org/licenses/mit-license.php
    public static void reverse(int[] b) {
    	   int left  = 0;          // index of leftmost element
    	   int right = b.length-1; // index of rightmost element
    	  
    	   while (left < right) {
    	      // exchange the left and right elements
    	      int temp = b[left]; 
    	      b[left]  = b[right]; 
    	      b[right] = temp;
    	     
    	      // move the bounds toward the center
    	      left++;
    	      right--;
    	   }
    }

    //function to generate a list of sums from 6 numbers
    //also add the 6 numbers to the list. and 0.
    //N=6, and 2^6=64, so this should be int[64].
    public int[] naive(int[] n) {
/*At this point I was torn between iterating through the possibilities
 *and regexing the resulting delineated string into the array's values, 
 *and just writing out all 64 possibilities by hand.
 *In the end, I decided that just writing it all out was probably
 *faster, both for the computer and for me.*/
    	int[] v = {0,n[0],n[1],n[2],n[3],n[4],n[5],
    			   n[0]+n[1],n[0]+n[2],n[0]+n[3],n[0]+n[4],n[0]+n[5],
    			   n[1]+n[2],n[1]+n[3],n[1]+n[4],n[1]+n[5],
    			   n[2]+n[3],n[2]+n[4],n[2]+n[5],
    			   n[3]+n[4],n[3]+n[5],
    			   n[4]+n[5],
    			   n[0]+n[1]+n[2],n[0]+n[1]+n[3],n[0]+n[1]+n[4],n[0]+n[1]+n[5],
    			   n[0]+n[2]+n[3],n[0]+n[2]+n[4],n[0]+n[2]+n[5],
    			   n[0]+n[3]+n[4],n[0]+n[3]+n[5],
    			   n[0]+n[4]+n[5],
    			   n[1]+n[2]+n[3],n[1]+n[2]+n[4],n[1]+n[2]+n[5],
    			   n[1]+n[3]+n[4],n[1]+n[3]+n[5],
    			   n[1]+n[4]+n[5],
    			   n[2]+n[3]+n[4],n[2]+n[3]+n[5],
    			   n[2]+n[4]+n[5],
    			   n[3]+n[4]+n[5],
    			   n[0]+n[1]+n[2]+n[3],n[0]+n[1]+n[2]+n[4],n[0]+n[1]+n[2]+n[5],
    			   n[0]+n[1]+n[3]+n[4],n[0]+n[1]+n[3]+n[5],
    			   n[0]+n[1]+n[4]+n[5],
    			   n[0]+n[2]+n[3]+n[4],n[0]+n[2]+n[3]+n[5],
    			   n[0]+n[2]+n[4]+n[5],
    			   n[0]+n[3]+n[4]+n[5],
    			   n[1]+n[2]+n[3]+n[4],n[1]+n[2]+n[3]+n[5],
    			   n[1]+n[2]+n[4]+n[5],
    			   n[1]+n[3]+n[4]+n[5],
    			   n[2]+n[3]+n[4]+n[5],
    			   n[0]+n[1]+n[2]+n[3]+n[4],n[0]+n[1]+n[2]+n[3]+n[5],
    			   n[0]+n[1]+n[2]+n[4]+n[5],
    			   n[0]+n[1]+n[3]+n[4]+n[5],
    			   n[0]+n[2]+n[3]+n[4]+n[5],
    			   n[1]+n[2]+n[3]+n[4]+n[5],
    			   n[0]+n[1]+n[2]+n[3]+n[4]+n[5]};
    	Arrays.sort(v);
    	return(v);
    }
    
    public int notrpn(String formula) {
    	int result = 0;
    	//I can't believe you have to put two slashes in this \/
    	String[] numbers = formula.split("\\+");
    	for (int i=0; i<numbers.length; i++) {
    		result += Integer.parseInt(numbers[i]);
    	}
    	return(result);
    }
    
    public void showtime(View view) {
    	int a[] = {0,0,0,0,0,0};
    	int b[] = {0,0,0,0,0,0};
    	EditText e = (EditText) findViewById(R.id.editText1);
    	a[0] = sanitize(e.getText().toString());    	
    	e = (EditText) findViewById(R.id.editText2);
    	a[1] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText3);
    	a[2] = sanitize(e.getText().toString());    	
    	e = (EditText) findViewById(R.id.editText4);
    	a[3] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText5);
    	a[4] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText6);
    	a[5] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText7);
    	b[0] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText8);
    	b[1] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText9);
    	b[2] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText10);
    	b[3] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText11);
    	b[4] = sanitize(e.getText().toString());
    	e = (EditText) findViewById(R.id.editText12);
    	b[5] = sanitize(e.getText().toString());
/*Eventually I realized that since I typed everything out in advance, I
 *had no any easy way to pull down exactly which items had gone into any
 *individual sum. Naturally, my solution to this problem was to type
 *everything out in advance. Again.
 *...Well, not "type", really, just a few Replaces in Notepad.
 *...And then realize that THOSE weren't being sorted the same way, so the
 *wrong numbers would show up.
 *So, I just had to iterate through them, converting to integer and
 *checking for equivalence.*/    			
    	int[] bear = naive(a);
    	String[] bear_s = {
 			   "0",Integer.toString(a[0]),Integer.toString(a[1]),Integer.toString(a[2]),Integer.toString(a[3]),Integer.toString(a[4]),Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1]),Integer.toString(a[0])+"+"+Integer.toString(a[2]),Integer.toString(a[0])+"+"+Integer.toString(a[3]),Integer.toString(a[0])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[2]),Integer.toString(a[1])+"+"+Integer.toString(a[3]),Integer.toString(a[1])+"+"+Integer.toString(a[4]),Integer.toString(a[1])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[2])+"+"+Integer.toString(a[3]),Integer.toString(a[2])+"+"+Integer.toString(a[4]),Integer.toString(a[2])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2]),Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[3]),Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3]),Integer.toString(a[0])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3]),Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[4]),Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[1])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[2])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3]),Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4]),Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5]),
 			   Integer.toString(a[0])+"+"+Integer.toString(a[1])+"+"+Integer.toString(a[2])+"+"+Integer.toString(a[3])+"+"+Integer.toString(a[4])+"+"+Integer.toString(a[5])
    	};
    	reverse(bear);			//bear is highest-to-lowest
    	int[] bull = naive(b);	//bull is lowest-to-highest
    	String[] bull_s = {
 			   "0",Integer.toString(b[0]),Integer.toString(b[1]),Integer.toString(b[2]),Integer.toString(b[3]),Integer.toString(b[4]),Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1]),Integer.toString(b[0])+"+"+Integer.toString(b[2]),Integer.toString(b[0])+"+"+Integer.toString(b[3]),Integer.toString(b[0])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[2]),Integer.toString(b[1])+"+"+Integer.toString(b[3]),Integer.toString(b[1])+"+"+Integer.toString(b[4]),Integer.toString(b[1])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[2])+"+"+Integer.toString(b[3]),Integer.toString(b[2])+"+"+Integer.toString(b[4]),Integer.toString(b[2])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2]),Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[3]),Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3]),Integer.toString(b[0])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3]),Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[4]),Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[1])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[2])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3]),Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4]),Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5]),
 			   Integer.toString(b[0])+"+"+Integer.toString(b[1])+"+"+Integer.toString(b[2])+"+"+Integer.toString(b[3])+"+"+Integer.toString(b[4])+"+"+Integer.toString(b[5])	
    	};
    	int x = 0;
    	int y = 0;
    	boolean exit = false;
    	String r = "No such luck.";
    	while (!exit) {
    		//You can't use "<40" in a switch statement's case. :(
    		if ((bear[x]+bull[y])==40) {
    			for (int i = 0; i < bear_s.length; i++) {
    				if (notrpn(bear_s[i]) == bear[x]) {
    					r = bear_s[i] + "+";
    					i = bear_s.length;
    				}
    			}
    			for (int i = 0; i < bull_s.length; i++) {
    				if (notrpn(bull_s[i]) == bull[y]) {
    					r += bull_s[i] + "=40!";
    					i = bull_s.length;
    				}
    			}
    			exit = true;
    		}
    		if ((bear[x]+bull[y])<40) {
    			if (y==(bull.length-1)) {
    				exit = true;
    			} else {
    				y++; //if too low, a higher number is used
    			}
    		}
    		if ((bear[x]+bull[y])>40) {
    			if (x==(bear.length-1)) {
    				exit = true;
    			} else {
    				x++; //if too high, a lower number is used
    			}
    		}
    	}
    	e = (EditText) findViewById(R.id.resultbox);
    	e.setText(r);
    	InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    	imm.hideSoftInputFromWindow(e.getWindowToken(), 0);
    }

}
